<?php

namespace App\Http\Controllers\Api\V1\App\Customers;

use App\Http\Controllers\ApiController;
use App\Http\Requests\Customers\ThirdParty\ThirdPartyCreateRequest;
use App\Http\Requests\Customers\ThirdParty\ThirdPartyShowRequest;
use App\Http\Services\Api\V1\App\Customer\AliPayService;
use App\Http\Services\Api\V1\App\Customer\FacebookService;
use App\Http\Services\Api\V1\App\Customer\GoogleService;
use App\Http\Services\Api\V1\App\Customer\LinkedInService;
use App\Http\Services\Api\V1\App\Customer\QqService;
use App\Http\Services\Api\V1\App\Customer\ThirdPartyService;
use App\Http\Services\Api\V1\App\Customer\TwitterService;
use App\Http\Services\Api\V1\App\Customer\WechatService;
use App\Services\MobileApp\AppEnv;
use App\Services\Utils\ApiChecker;
use Illuminate\Http\Request;
use Service\AlipayOpenPlatform\AopFactory;

class ThirdPartyLoginController extends ApiController
{
    use ApiChecker;

    const SETTING_OAUTH_OAUTH = 'oauth_';
    const SETTING_OAUTH_APP = '_app';

    const THIRD_PARTY_WECHAT_APP = 'wechat_app';
    const THIRD_PARTY_WECHAT_PC = 'wechat_pc';
    const THIRD_PARTY_ALIPAY_APP = 'alipay_app';
    const THIRD_PARTY_ALIPAY_PC = 'alipay_pc';
    const THIRD_PARTY_QQ_APP = 'qq_app';
    const THIRD_PARTY_QQ_PC = 'qq_pc';
    const THIRD_PARTY_FACEBOOK_APP = 'facebook_app';
    const THIRD_PARTY_FACEBOOK_PC = 'facebook_pc';
    const THIRD_PARTY_TWITTER_APP = 'twitter_app';
    const THIRD_PARTY_TWITTER_PC = 'twitter_pc';
    const THIRD_PARTY_GOOGLE_APP = 'google_app';
    const THIRD_PARTY_GOOGLE_PC = 'google_pc';
    const THIRD_PARTY_LINKEDIN_APP = 'linkedin_app';
    const THIRD_PARTY_LINKEDIN_PC = 'linkedin_pc';

    private $third_party;

    public function __construct()
    {
        $this->third_party = new ThirdPartyService;
    }

    /**
     * app端，返回第三方登录的配置信息。
     *
     * @return array|\Illuminate\Http\Response
     */
    public function create()
    {
        $store_id = AppEnv::storeId();

        $socialite_login_setting = $this->third_party->getThirdPartySetting($store_id, self::SETTING_OAUTH_APP);

        return $this->response(compact('socialite_login_setting'));
    }

    /**
     * app端，返回签名：infoStr。
     *
     * @return array|\Illuminate\Http\Response
     */
    public function generateAliPaySign()
    {
        $sign = (new AliPayService)->getAppSign();

        return $this->response(compact('sign'));
    }

    /**
     * 第三方登录，app端，根据code获取登录用户的信息。
     *
     * @param ThirdPartyShowRequest $request
     * @param $type
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function show(ThirdPartyShowRequest $request, $type)
    {
        switch($type)
        {
            case self::THIRD_PARTY_WECHAT_APP:

                $customer = (new WechatService)->handleWechatCallback();
                break;
            case self::THIRD_PARTY_ALIPAY_APP:

                $customer = $this->third_party->handleAlipayCallback();
                break;
            case self::THIRD_PARTY_QQ_APP:

                $customer = (new QqService)->handleQqCallback();
                break;
            case self::THIRD_PARTY_FACEBOOK_APP:

                $customer = (new FacebookService($type))->handleFacebookCallback();
                break;
            case self::THIRD_PARTY_TWITTER_APP:

                $customer = (new TwitterService($type))->handleTwitterCallback();
                break;
            case self::THIRD_PARTY_GOOGLE_APP:

                $customer = (new GoogleService($type))->handleGoogleCallback();
                break;
            case self::THIRD_PARTY_LINKEDIN_APP:

                $customer = (new LinkedInService($type))->handleLinkedInCallback();
                break;
            default:
                $this->checkIsTrue(false, trans('customer.illegal_oauth_type'));
        }

        return $this->response(compact('customer'));
    }

    /**
     * 第三方登录，pc端（qq，twitter，google，facebook， linkedin）请求授权地址
     *
     * @param $type
     * @return mixed
     * @throws \Exception
     */
    public function redirectToProvider($type)
    {
        switch($type)
        {
            case self::THIRD_PARTY_QQ_PC:

                $provider = (new QqService)->generateQqProvider();
                break;
            case self::THIRD_PARTY_FACEBOOK_PC:

                $provider = (new FacebookService($type))->generateFacebookProvider();
                break;
            case self::THIRD_PARTY_TWITTER_PC:

                $provider = (new TwitterService($type))->generateTwitterProvider();
                break;
            case self::THIRD_PARTY_GOOGLE_PC:

                $provider = (new GoogleService($type))->generateGoogleProvider();
                break;
            case self::THIRD_PARTY_LINKEDIN_PC:

                $provider = (new LinkedInService($type))->generateLinkedInProvider();
                break;
            default:
                $this->checkIsTrue(false, trans('customer.illegal_oauth_type'));
        }

        return $provider->redirect();
    }

    /**
     * 第三方登录，pc端（qq，twitter，google，facebook， linkedin）授权回调地址
     *
     * 国外应用获取access_token和user，要翻墙。
     * 加上代理：
     * $opts['proxy'] = ['http'  => 'http://localhost:1080','https' => 'http://localhost:1080'];
     * $opts['verify'] = false;
     * @see \GuzzleHttp\Client::__call
     *
     * @param $type
     * @return \App\Models\Customers\Customer|array|\Illuminate\Database\Eloquent\Model|null|object
     * @throws \Exception
     */
    public function handleProviderCallback($type)
    {
        switch($type)
        {
            case self::THIRD_PARTY_QQ_PC:

                $user = (new QqService)->qqCallback();
                break;
            case self::THIRD_PARTY_FACEBOOK_PC:

                $user = (new FacebookService($type))->facebookCallback();
                break;
            case self::THIRD_PARTY_TWITTER_PC:

                $user = (new TwitterService($type))->twitterCallback();
                break;
            case self::THIRD_PARTY_GOOGLE_PC:

                $user = (new GoogleService($type))->googleCallback();
                break;
            case self::THIRD_PARTY_LINKEDIN_PC:

                $user = (new LinkedInService($type))->linkedInCallback();
                break;
            default:
                $this->checkIsTrue(false, trans('customer.illegal_oauth_type'));
        }

        return $user;
    }
}
